﻿using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Globalization;
using System.IO;
using System.Text.RegularExpressions;
using System.Web;

namespace DusonFramework.Core.Web.Images
{
    public class ImagesHelper
    {
        public static byte[] GetFileStream(HttpPostedFile objFile)
        {
            if (objFile != null)
            {
                int len = objFile.ContentLength;
                byte[] input = new byte[len];
                Stream file = objFile.InputStream;
                file.Read(input, 0, len);
                return input;
            }
            return null;
        }

        public static bool ValidateFile(string filepath)
        {
            if (File.Exists(filepath))
            {
                return false;
            }

            return Regex.IsMatch(filepath,
                "(?:[^\\/\\*\\?\\\"\\<\\>\\|\\n\\r\\t]+)\\.(?:jpg|jpeg|gif|png|bmp)",
                RegexOptions.IgnoreCase | RegexOptions.CultureInvariant
                );
        }

        public static Size ResizeImage(int width, int height, int maxWidth, int maxHeight)
        {
            decimal MAX_WIDTH = maxWidth;
            decimal MAX_HEIGHT = maxHeight;
            decimal ASPECT_RATIO = MAX_WIDTH / MAX_HEIGHT;

            int newWidth, newHeight;

            decimal originalWidth = width;
            decimal originalHeight = height;

            if (originalWidth > MAX_WIDTH || originalHeight > MAX_HEIGHT)
            {
                decimal factor;
                // determine the largest factor 
                if (originalWidth / originalHeight > ASPECT_RATIO)
                {
                    factor = originalWidth / MAX_WIDTH;
                    newWidth = Convert.ToInt32(originalWidth / factor);
                    newHeight = Convert.ToInt32(originalHeight / factor);
                }
                else
                {
                    factor = originalHeight / MAX_HEIGHT;
                    newWidth = Convert.ToInt32(originalWidth / factor);
                    newHeight = Convert.ToInt32(originalHeight / factor);
                }
            }
            else
            {
                newWidth = width;
                newHeight = height;
            }

            return new Size(newWidth, newHeight);

        }

        public static bool SaveImage(byte[] Buffer, string FileName)
        {

            if (ValidateFile(FileName))
            {
                CheckDirectory(FileName);
                FileStream fs = new FileStream(FileName, FileMode.Create);
                fs.Write(Buffer, 0, Buffer.Length);
                fs.Close();
                return true;
            }
            return false;
        }

        /// <summary>
        /// Saves two images. A normal image for the web site and then a thumbnail.
        /// </summary>
        /// <param name="image">Original image to process.</param>
        //public static void MakeAlbumImages()
        //{
        //    System.Drawing.Image originalImage = System.Drawing.Image.FromFile(image.OriginalFilePath);

        //    // Need to load the original image to manipulate. But indexed GIFs can cause issues.
        //    if ((originalImage.PixelFormat & PixelFormat.Indexed) != 0)
        //    {
        //        // Draw the index image to a new bitmap.  It will then be unindexed.
        //        System.Drawing.Image unindexedImage = new Bitmap(originalImage.Width, originalImage.Height);
        //        Graphics g = Graphics.FromImage(unindexedImage);
        //        g.DrawImageUnscaled(originalImage, 0, 0);

        //        originalImage.Dispose();
        //        originalImage = unindexedImage;
        //    }

        //    // Dispose the original graphic (be kind; clean up)
        //    using (originalImage)
        //    {
        //        /// TODO: make both sizes configurations. 
        //        // Calculate the new sizes we want (properly scaled) 
        //        Size displaySize = ResizeImage(originalImage.Width, originalImage.Height, 640, 480);
        //        Size thumbSize = ResizeImage(originalImage.Width, originalImage.Height, 120, 120);

        //        // Tell the object what its new display size will be
        //        image.Height = displaySize.Height;
        //        image.Width = displaySize.Width;

        //        // Create a mid-size display image by drawing the original image into a smaller area.
        //        using (System.Drawing.Image displayImage = new Bitmap(displaySize.Width, displaySize.Height, originalImage.PixelFormat))
        //        {
        //            using (Graphics displayGraphic = Graphics.FromImage(displayImage))
        //            {
        //                displayGraphic.CompositingQuality = CompositingQuality.HighQuality;
        //                displayGraphic.SmoothingMode = SmoothingMode.HighQuality;
        //                displayGraphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
        //                Rectangle displayRectangle = new Rectangle(0, 0, displaySize.Width, displaySize.Height);
        //                displayGraphic.DrawImage(originalImage, displayRectangle);
        //                // Save our file
        //                displayImage.Save(image.ResizedFilePath, ImageFormat.Jpeg);
        //            }
        //        }

        //        // Create a small thumbnail
        //        using (System.Drawing.Image thumbImage = new Bitmap(thumbSize.Width, thumbSize.Height, originalImage.PixelFormat))
        //        {
        //            using (Graphics thumbGraphic = Graphics.FromImage(thumbImage))
        //            {
        //                thumbGraphic.CompositingQuality = CompositingQuality.HighQuality;
        //                thumbGraphic.SmoothingMode = SmoothingMode.HighQuality;
        //                thumbGraphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
        //                Rectangle thumbRectangle = new Rectangle(0, 0, thumbSize.Width, thumbSize.Height);
        //                thumbGraphic.DrawImage(originalImage, thumbRectangle);
        //                // Save our file
        //                thumbImage.Save(image.ThumbNailFilePath, ImageFormat.Jpeg);
        //            }
        //        }
        //    }
        //}

        public static string GetFileName(string filepath)
        {
            if (filepath.IndexOf("\\") == -1)
            {
                return StripUrlCharsFromFileName(filepath);
            }
            else
            {
                int lastindex = filepath.LastIndexOf("\\");
                return StripUrlCharsFromFileName(filepath.Substring(lastindex + 1));
            }
        }

        private static string StripUrlCharsFromFileName(string filename)
        {
            const string replacement = "_";

            filename = filename.Replace("#", replacement);
            filename = filename.Replace("&", replacement);
            filename = filename.Replace("%", replacement);

            return filename;
        }

        public static void CheckDirectory(string filepath)
        {
            string dir = filepath.Substring(0, filepath.LastIndexOf("\\"));
            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }
        }

        #region 图片格式转换
        /// <summary>
        /// 图片格式转换
        /// </summary>
        /// <param name="OriFilename">原始文件相对路径</param>
        /// <param name="DesiredFilename">生成目标文件相对路径</param>
        /// <returns></returns>
        ///  JPG采用的是有损压缩所以JPG图像有可能会降低图像清晰度，而像素是不会降低的   
        ///  GIF采用的是无损压缩所以GIF图像是不会降低原图图像清晰度和像素的，但是GIF格式只支持256色图像。
        public static bool ConvertImage(string oriFilename, string desiredFilename)
        {
            string extname = desiredFilename.Substring(desiredFilename.LastIndexOf('.') + 1).ToLower();
            ImageFormat DesiredFormat;
            //根据扩张名，指定ImageFormat
            switch (extname)
            {
                case "bmp":
                    DesiredFormat = ImageFormat.Bmp;
                    break;
                case "gif":
                    DesiredFormat = ImageFormat.Gif;
                    break;
                case "jpeg":
                    DesiredFormat = ImageFormat.Jpeg;
                    break;
                case "ico":
                    DesiredFormat = ImageFormat.Icon;
                    break;
                case "png":
                    DesiredFormat = ImageFormat.Png;
                    break;
                default:
                    DesiredFormat = ImageFormat.Jpeg;
                    break;
            }
            try
            {
                System.Drawing.Image imgFile = System.Drawing.Image.FromFile(HttpContext.Current.Server.MapPath(oriFilename));
                imgFile.Save(HttpContext.Current.Server.MapPath(desiredFilename), DesiredFormat);
                return true;
            }
            catch
            {
                return false;
            }
        }
        #endregion


        #region 图片缩放
        /// <summary>
        /// 图片固定大小缩放
        /// </summary>
        /// <param name="OriFileName">源文件相对地址</param>
        /// <param name="DesiredFilename">目标文件相对地址</param>
        /// <param name="IntWidth">目标文件宽</param>
        /// <param name="IntHeight">目标文件高</param>
        /// <param name="imageFormat">图片文件格式</param>
        public static bool ChangeImageSize(string oriFileName, string desiredFilename, int intWidth, int intHeight, ImageFormat imageFormat)
        {
            string SourceFileNameStr = HttpContext.Current.Server.MapPath(oriFileName); //来源图片名称路径
            string TransferFileNameStr = HttpContext.Current.Server.MapPath(desiredFilename); //目的图片名称路径
            FileStream myOutput = null;
            try
            {
                System.Drawing.Image.GetThumbnailImageAbort myAbort = new System.Drawing.Image.GetThumbnailImageAbort(imageAbort);
                Image SourceImage = System.Drawing.Image.FromFile(oriFileName);//来源图片定义
                Image TargetImage = SourceImage.GetThumbnailImage(intWidth, intHeight, myAbort, IntPtr.Zero);  //目的图片定义
                //将TargetFileNameStr的图片放宽为IntWidth，高为IntHeight 
                myOutput = new FileStream(TransferFileNameStr, FileMode.Create, FileAccess.Write, FileShare.Write);
                TargetImage.Save(myOutput, imageFormat);
                myOutput.Close();
                return true;
            }
            catch
            {
                myOutput.Close();
                return false;
            }


        }

        private static bool imageAbort()
        {
            return false;
        }
        #endregion


        #region 文字水印
        /// <summary>
        /// 文字水印
        /// </summary>
        /// <param name="wtext">水印文字</param>
        /// <param name="source">原图片物理文件名</param>
        /// <param name="target">生成图片物理文件名</param>
        public static bool ImageWaterText(string wtext, string source, string target)
        {
            bool resFlag = false;
            Image image = Image.FromFile(source);
            Graphics graphics = Graphics.FromImage(image);
            try
            {
                graphics.DrawImage(image, 0, 0, image.Width, image.Height);
                Font font = new System.Drawing.Font("Verdana", 60);
                Brush brush = new System.Drawing.SolidBrush(System.Drawing.Color.Green);
                graphics.DrawString(wtext, font, brush, 35, 35);
                image.Save(target);
                resFlag = true;
            }
            catch (Exception)
            {

                throw;
            }
            finally
            {
                graphics.Dispose();
                image.Dispose();

            }
            return resFlag;
        }


        #endregion


        #region 图片水印

        /// <summary>
        /// 在图片上生成图片水印
        /// </summary>
        /// <param name="Path">原服务器图片路径</param>
        /// <param name="Path_syp">生成的带图片水印的图片路径</param>
        /// <param name="Path_sypf">水印图片路径</param>
        public static bool ImageWaterPic(string source, string target, string waterPicSource)
        {
            bool resFlag = false;
            Image sourceimage = Image.FromFile(source);
            Graphics sourcegraphics = Graphics.FromImage(sourceimage);
            Image waterPicSourceImage = Image.FromFile(waterPicSource);
            try
            {
                sourcegraphics.DrawImage(waterPicSourceImage, new System.Drawing.Rectangle(sourceimage.Width - waterPicSourceImage.Width, sourceimage.Height - waterPicSourceImage.Height, waterPicSourceImage.Width, waterPicSourceImage.Height), 0, 0, waterPicSourceImage.Width, waterPicSourceImage.Height, GraphicsUnit.Pixel);
                sourceimage.Save(target);
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                sourcegraphics.Dispose();
                sourceimage.Dispose();
                waterPicSourceImage.Dispose();
            }
            return resFlag;

        }

        #endregion
    }

}
